<template>
    <div class="chat">
        <el-container style="height:100%">
            <el-aside width="300px" class="side" style="height:100%;overflow:auto;">
                <div class="server-card" v-for="server in mcpServers">
                    <div><span>服务名称：</span><span>{{ server.name }}</span></div>
                    <div><span>服务命令：</span><span>{{ server.command }}</span></div>
                    <div><span>服务参数：</span><span>{{ JSON.stringify(server.args, null, 2) }}</span></div>
                </div>
            </el-aside>
            <el-main class="body">
                <chat ref="chatBox" v-model:messages="history" @message-send="sendMessageHandle"
                      :process-config="processConfig">
                    align="leftright">
                </chat>
            </el-main>
        </el-container>
    </div>
</template>
<script setup>
import {ref, reactive, onMounted, nextTick} from 'vue'
import chat from '../chat/Index.vue'
import {doChat} from '@/api/chat.js'
import {fetchEventSource} from "@microsoft/fetch-event-source";
import request from "@/utils/request.js";

const props = defineProps({})
const emits = defineEmits([])
const mcpServers = reactive([])
const userInput = ref('开始游戏');
const loading = ref(false)
const processConfig = {
    processTitle: 'AI Agent',
    processType: {
        logger: '日志',
        nodeInput: '智能体入参',
        nodeOutput: '智能体输出',
        toolInput: '工具入参',
        toolOutput: '工具出参'
    }
}
const history = ref(
    [
        {
            role: 'system',
            id: '1',
            createAt: 1715676751919,
            content: "您好，我是您的人工智能助手。您可以尝试问我以下问题。",
            suggest: [
                "查询我的工作规划，我的目录是：E:/Projects/MCP_Resources",
                "查询郑州天气"
            ]
        }
    ]
)
const cmessage = ref('')
const chatBox = ref(null)
let abortController = null

const test = () => {
    let count = 0
    const source = new EventSource("http://127.0.0.1:8911/agent/endless")
    source.onmessage = function (event) {
        // 接收到服务器端发送的数据时触发
        count++
        if (count === 10) {
            source.close()
        }
        console.log(event)
    };
    source.onerror = function (event) {
        // 接收到服务器端发送的数据时触发
        console.log(event)
    };
    source.onopen = function (event) {
        // 接收到服务器端发送的数据时触发
        console.log(event)
    };

}


const sendMessageHandle = (message) => {
    console.log('sendMessageHandle', message)
    history.value.push({
        role: 'user',
        id: new Date().getTime(),
        createAt: new Date().getTime(),
        content: message,
    })
    history.value.push({
        role: 'assistant',
        id: new Date().getTime() + 2,
        createAt: new Date().getTime(),
        content: '',
        status: 'loading',
        process: []
    })


    abortController = new AbortController();
    let fullMessage = ''
    let data = {
        "message": message
    }
    let processGroupId = 1

    const init = {
        method: 'post',
        signal: abortController.signal,
        openWhenHidden: true, // 取消visibilityChange事件
        headers: {
            "Content-Type": `application/json`,
        },
        onopen(ev) {
            console.log(ev)
        },
        async onmessage(ev) {
            try {
                let nowChat = history.value.slice(-1)[0]
                let respData = JSON.parse(ev.data)
                if (respData.type === 'final') {
                    nowChat.content += respData.message
                    nowChat.status = 'success'
                } else if (respData.type === 'toolCall') {
                    ++processGroupId
                    const toolCallParams = JSON.parse(respData.message)
                    nowChat.process.push({
                        groupId: processGroupId,
                        type: 'toolStart',
                        groupName: '开始执行工具:' + toolCallParams.function.name,
                    })
                    nowChat.process.push({
                        groupId: processGroupId,
                        type: 'toolInput',
                        data: toolCallParams,
                    })
                } else if (respData.type === 'toolResult') {
                    nowChat.process.push({
                        groupId: processGroupId,
                        type: 'toolOutput',
                        data: respData.message,
                    })
                }
            } catch (e) {
                console.error(e)
            }
        },
        onclose(ev) {
            loading.value = false;
            abortController && abortController.abort();
        },
        onerror(err) {
            // console.log("onerror:", err);
            loading.value = false;
            abortController.abort();
            eventSource.close();
        },
    };

    data && (init.body = JSON.stringify(data));
    // headers && (init.headers = headers);
    const eventSource = fetchEventSource(`http://localhost:3220/completion`, init);

//     todo 发送消息到后端
}

const getMcpServers = async () => {
    const response = await request({
        method: 'GET',
        url: 'http://127.0.0.1:3220/listServer',
    })
    mcpServers.splice(0, mcpServers.length)
    for (let name in response) {
        console.log(name)
        mcpServers.push({
            name: name,
            ...(response[name] || {}),
        })
    }
    console.log(response)
}

onMounted(() => {
    // test()
    getMcpServers()
})
/**
 * 提交
 */
const submit = () => {
    console.log(userInput.value);
    history.value.push({
        role: 'user',
        content: userInput.value
    })
    chatStreamAnswer({
        chat_id: 'abcd',
        content: userInput.value,
        userMessage: userInput.value,
    })
}

//流式回答  是一个模块完成输出一个模块，不是一个字一个字的输出
const chatStreamAnswer = (data) => {
    const baseURL = import.meta.env.VITE_BASE_API_URL
    const url = '/ai/agents/chairman'//'/agent/multi_agent_stream'

    abortController = new AbortController();
    let message = ''

    const init = {
        method: 'post',
        signal: abortController.signal,
        openWhenHidden: true, // 取消visibilityChange事件
        headers: {
            "Content-Type": `application/json`,
        },
        onopen(ev) {
            console.log(ev)
        },
        async onmessage(ev) {
            try {
                data = JSON.parse(ev.data)
                if (!data.isFinished) {
                    // message += data.content
                    message += data
                } else {
                    history.value.push({
                        role: 'assistant',
                        content: data
                        // content: data.content//message
                    })
                    message = ''
                }
                cmessage.value += data
                // cmessage.value += data.content
                await nextTick()
            } catch (e) {
                console.error(e)
            }
        },
        onclose(ev) {
            loading.value = false;
            abortController && abortController.abort();
        },
        onerror(err) {
            // console.log("onerror:", err);
            loading.value = false;
            abortController.abort();
            eventSource.close();
        },
    };

    data && (init.body = JSON.stringify(data));
    // headers && (init.headers = headers);
    const eventSource = fetchEventSource(`${baseURL}${url}`, init);
}

</script>
<style lang="scss" scoped>
.chat {
    position: relative;
    height: 100%;
    width: 100%;

    .header {
        border-bottom: 1px solid #eee;
    }

    .side {
        border-right: 1px solid #eee;
        display: flex;
        flex-direction: column;
        padding-right: 10px;

        .server-card {
            padding: 16px;
            margin: 16px 0;
            border-radius: 8px;
            background-color: #fff;

            > div {
                padding: 6px 4px;
                overflow: hidden;

                > span:last-child {
                    color: #646363;
                }

                > span {

                    word-break: break-word;
                }
            }
        }
    }

    .body {
        position: relative;
        display: flex;
        flex-direction: column;
        padding: 20px 100px;

        .his-content {
            flex: 1;
            width: 100%;
            height: max-content;
        }

        .prompt {
            width: 100%;
            height: 180px;
        }
    }
}
</style>